/*
 * File: vfsdriver.c
 *
 * Description: This is a driver program for testing your VFS system using an interaction script as input
 * You need to make additional calls to your respective functions as noted in the comments below
 * Make sure the output you display is exactly as per the given specifications for you. Do NOT print
 * any extra output (like debug messages) in the final version of your driver program. You can use this driver program
 * in a in incremental manner as you keep implementing one operator after another. For operators not yet implemented,
 * you can leave the output as given ("TO_BE_DONE"). So you can use this program as your "main" program for testing purposes.
 *
 * DO NOT write the full code for operators in the driver program! You must only CALL your functions from here.
 *
 * Usage: vfsdriver <scriptfilename>
 */

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#include "../include/FileSystemOperations.h"
#include "../include/DirectoryOperations.h"
#include "../include/NAry.h"
#include "../include/FileOperations.h"
#include "../include/vfs_errorcodes.h"

#define BUFSIZE 200
#define CMDSIZE 30
#define PARSIZE 100

void createvfs ( char *P1, int P2 );
void mountvfs ( char *P1 );
void unmountvfs ( char *P1 );
void makedir ( char *P1, char *P2);
void deletedir ( char *P1, int);
void movedir ( char *P1, char *P2 );
void listdir ( char *P1, int P2, char *P3 );
void addfile ( char *P1, char *P2, char *P3 );
void listfile ( char *P1, char *P2 );
void updatefile ( char *P1, char *P2 );
void removefile ( char *P1 );
void movefile ( char *P1, char *P2 );
void copyfile ( char *P1, char *P2 );
void exportfile ( char *P1, char *P2 );
void searchfile ( char *P1, char *P2 );
void searchcontent( char *P1, char *P2 );

void processcommand( char *command, char *P1, char *P2, char *P3 );

FILE *fp;

int main( int argc, char *argv[] )
{
	FILE *scriptfp;
	char linebuffer[BUFSIZE];
	char command[CMDSIZE], par1[PARSIZE], par2[PARSIZE], par3[PARSIZE];
	char *token;
	fp = fopen("vfsoutput.txt", "w+");
	if( argc != 2 ){
		fprintf(stderr,"Usage: vfsdriver <scriptfile>\n");
		return(1);
	}

	if( (scriptfp=fopen(argv[1],"r")) == NULL ){
		fprintf(stderr,"Unable to open script file: %s\n", argv[1]);
		return(2);
	}
	
	while( fgets(linebuffer, sizeof(linebuffer), scriptfp) != NULL  ){
		/* This output is for debugging... do not uncomment in final version */
		/*
		printf("\n==================================================\n");
		printf("\nProcessing: %s", linebuffer);
		printf("\n==================================================\n");
		*/
		/* Get the command and the parameters using tokenizer */
		strcpy( command, (token = strtok(linebuffer, " \n")) == NULL ? "" : token );
		
		strcpy( par1, (token = strtok(NULL, " \n")) == NULL ? "" : token );
		strcpy( par2, (token = strtok(NULL, " \n")) == NULL ? "" : token );
		strcpy( par3, (token = strtok(NULL, " \n")) == NULL ? "" : token );
		//printf("\nCommand:%s:p1:%s:p2:%s:p3:%s\n",command, par1, par2, par3); 

		processcommand( command, par1, par2, par3 );
	}
	fclose(fp);
}

void processcommand( char *command, char *P1, char *P2, char *P3 )
{
	
	if(P1[strlen(P1)-1]=='\n')
		P1[strlen(P1)-1]='\0';
	if(P2[strlen(P2)-1]=='\n')
		P2[strlen(P2)-1]='\0';
	if(P3[strlen(P3)-1]=='\n')
		P3[strlen(P3)-1]='\0';

	if( strcmp(command, "createvfs") == 0 ){
		int size;
		if(strcmp(P2, "")==0)
			size=-4567;
		else
			size = atoi(P2);
		createvfs (P1,size);
	}
	else if( strcmp(command, "mountvfs") == 0 )
		mountvfs (P1);
	else if( strcmp(command, "unmountvfs") == 0 )
		unmountvfs (P1);
	else if( strcmp(command, "makedir") == 0 )
		makedir (P1,P2);
	else if( strcmp(command, "deletedir") == 0 ){
		int flag;
		if(strcmp(P2,"")==0)
			flag = 0;
		else
			flag = atoi(P2);
		deletedir (P1, flag);

	}
	else if( strcmp(command, "movedir") == 0 )
		movedir (P1,P2);
	else if( strcmp(command, "listdir") == 0 ){
		int flag = atoi(P2);
		listdir (P1,flag,P3);
	}
	else if( strcmp(command, "addfile") == 0 )
		addfile (P1,P2,P3);
	else if( strcmp(command, "listfile") == 0 )
		listfile (P1,P2);
	else if( strcmp(command, "updatefile") == 0 )
		updatefile (P1,P2);
	else if( strcmp(command, "removefile") == 0 )
		removefile (P1);
	else if( strcmp(command, "movefile") == 0 )
		movefile (P1,P2);
	else if( strcmp(command, "copyfile") == 0 )
		copyfile (P1,P2);
	else if( strcmp(command, "exportfile") == 0 )
		exportfile (P1,P2);
	else if( strcmp(command, "searchfile") == 0 )
		searchfile (P1,P2);
	else if( strcmp(command, "searchcontent") == 0 )
		searchcontent(P1, P2);
	else
		printf("Ignoring invalid command %s\n", command);
}
void createvfs ( char *P1, int P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	int statusCode;
	if(P2!=-4567)
		statusCode = create_vfs(P1, P2);
	else
		statusCode = 0;
	if(statusCode!=-1)
		printf("createvfs_FAILURE ");
	switch(statusCode)
	{
		case -1: printf("createvfs_SUCCESS\n");
			break;
		
		case 1: printf("%s\n", ERR_VFS_CREATE_01);
			break;
		case 2: printf("%s\n", ERR_VFS_CREATE_02);
			break;
		case 3: printf("%s\n", ERR_VFS_CREATE_03);
			break;  
		case 4: printf("%s\n", ERR_VFS_CREATE_04);
			break;
		case 5: printf("%s\n", ERR_VFS_CREATE_05);
			break;
		case 0: printf("%s\n", ERR_VFS_CREATE_00);
			break;
		/*case 7: printf("\n%s", ERR_VFS_CREATE_07);
			break;	*/		
		
		default: printf("Unknown Error\n");
	}
}

void mountvfs ( char *P1 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	int statusCode = mount_vfs(P1);
	if(statusCode!=-1)
		printf("mountvfs_FAILURE ");
	switch(statusCode)
	{
		case -1: printf("mountvfs_SUCCESS\n");
			break;
		case 1: printf("%s\n", ERR_VFS_MOUNT_01);
			break;
		case 2: printf("%s\n", ERR_VFS_MOUNT_02);
			break;
		/*case 3: printf("%s\n", ERR_VFS_MOUNT_03);*/
		case 4: printf("%s\n", ERR_VFS_MOUNT_03);
			break;
		case 0: printf("%s\n", ERR_VFS_MOUNT_00);
			break;
	}
}

void unmountvfs ( char *P1 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	int statusCode = unmount_vfs(P1);
	if(statusCode!=-1)
		printf("unmountvfs_FAILURE ");
	
	switch(statusCode)
	{
		case -1: printf("unmountvfs_SUCCESS\n");
			break;
		case 1: printf("%s\n", ERR_VFS_UNMOUNT_01);
			break;
		case 2: printf("%s", ERR_VFS_UNMOUNT_02);
			break;
		case 3: printf("%s\n", ERR_VFS_UNMOUNT_03);
			break;
		case 0: printf("%s\n", ERR_VFS_UNMOUNT_00);
			break;		
	}
}

void makedir ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	//FILE *fp;
	//fp=fopen("outputfile.txt","a");
	int statusCode = make_dir(P1, P2 );
	if(statusCode!=-1)
		printf("makedir_FAILURE ");
	switch(statusCode)
	{
		case -1: printf("makedir_SUCCESS\n");
			break;
		case 0: printf("%s\n",ERR_VFS_MAKEDIR_00);
			break;
		case 1: printf("%s\n", ERR_VFS_MAKEDIR_01);
			break;
		case 2: printf("%s\n", ERR_VFS_MAKEDIR_02);
			break;
		case 3: printf("%s\n", ERR_VFS_MAKEDIR_03);
			break;
		case 5: printf("%s\n", ERR_VFS_MAKEDIR_05);
			break;

	}
	//fclose(fp);
}

void deletedir ( char *P1 ,int flag)
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	//FILE *fp;
	//fp=fopen("outputfile.txt","a");
	int statusCode = delete_dir(P1, flag);
	if(statusCode!=-1)
		printf("deletedir_FAILURE ");
	switch(statusCode)
	{
		case -1: printf("deletedir_SUCCESS\n");
			break;
		case 0: printf("%s\n",ERR_VFS_DELETEDIR_00);
			break;
		case 1: printf("%s\n", ERR_VFS_DELETEDIR_01);
			break;
		case 2: printf("%s\n", ERR_VFS_DELETEDIR_02);
			break;
		/*case 3: printf("%s", ERR_VFS_DELETEDIR_03);
			break;
		*/
		case 4: printf("%s\n", ERR_VFS_DELETEDIR_04);
			break;
	}
	//fclose(fp);
}

void movedir ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	//FILE *fp;
	//fp=fopen("outputfile.txt","a");
	//printf("movedir_TO_BE_DONE\n");	
	int statusCode = move_dir(P1, P2);
	if(statusCode!=-1)
		printf("movedir_FAILURE ");
	switch(statusCode)
	{
		
		case -1: printf("movedir_SUCCESS\n");
			break;
		case 0: printf("%s\n",ERR_VFS_MOVEDIR_00);
			break;
		case 1: printf("%s\n", ERR_VFS_MOVEDIR_01);
			break;
		case 2: printf("%s\n", ERR_VFS_MOVEDIR_02);
			break;
		case 4: printf("%s\n", ERR_VFS_MOVEDIR_04);
			break;
		case 5: printf("%s\n", ERR_VFS_MOVEDIR_05);
			break;
		case 6: printf("%s\n", ERR_VFS_MOVEDIR_06);
			break;
		case 7: printf("%s\n", ERR_VFS_MOVEDIR_07);
			break;
		case 8: printf("%s\n", ERR_VFS_MOVEDIR_08);
			break;
	}
//	fclose(fp);
}

void listdir ( char *P1, int P2, char *P3 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
//	FILE *fp;
//	fp=fopen("outputfile.txt","a");
	//printf("listdir_TO_BE_DONE\n");
	int statusCode = list_dir(P1, P2, P3);
	if(statusCode!=-1)
		printf("listdir_FAILURE ");
	switch(statusCode)
	{
		case -1: printf("listdir_SUCCESS\n");
			break;
		case 0: printf("%s\n",ERR_VFS_LISTDIR_00);
			break;
		case 1: printf("%s\n", ERR_VFS_LISTDIR_01);
			break;
		case 2: printf("%s\n", ERR_VFS_LISTDIR_02);
			break;
		case 3: printf("%s\n", ERR_VFS_LISTDIR_03);
			break;
		case 4: printf("%s\n", ERR_VFS_LISTDIR_04);
			break;
	}
//	fclose(fp);
}

void addfile ( char *P1, char *P2, char *P3 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	int statusCode = add_file(P1, P2, P3);
	if(statusCode!=-1)
		printf("addfile_FAILURE ");
	switch(statusCode)
	{
		case -1: printf("addfile_SUCCESS\n");
			break;
		case 0: printf("%s\n", ERR_VFS_ADDFILE_00);
			break;
		case 2: printf("%s\n", ERR_VFS_ADDFILE_02);
			break;
		case 3: printf("%s\n", ERR_VFS_ADDFILE_03);
			break;
		case 4: printf("%s\n", ERR_VFS_ADDFILE_04);
			break;
		case 5: printf("%s\n", ERR_VFS_ADDFILE_05);
			break;
		case 6: printf("%s\n", ERR_VFS_ADDFILE_06);
			break;
		case 7: printf("%s\n", ERR_VFS_ADDFILE_07);
			break;
	}

}

void listfile ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	int statusCode = list_file(P1, P2);
	if(statusCode!=-1)
		printf("listfile_FAILURE ");
	switch(statusCode)
	{
		case -1: printf("listfile_SUCCESS\n");
			break;
		case 0: printf("%s\n", ERR_VFS_LISTFILE_00);
			break;
		case 1: printf("%s\n", ERR_VFS_LISTFILE_01);
			break;
		case 2: printf("%s\n", ERR_VFS_LISTFILE_02);
			break;
		case 3: printf("%s\n", ERR_VFS_LISTFILE_03);
			break;
		case 4: printf("%s\n", ERR_VFS_LISTFILE_04);
			break;
	}
	
}

void updatefile ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	int statusCode=update_file(P1,P2);
	if(statusCode!=-1)
		printf("updatefile_FAILURE ");
	switch(statusCode)
	{
		case -1: printf("updatefile_SUCCESS\n");
			break;
		case 0: printf("%s\n", ERR_VFS_UPDATEFILE_00);
			break;
		case 1: printf("%s\n", ERR_VFS_UPDATEFILE_01);
			break;
		case 2: printf("%s\n", ERR_VFS_UPDATEFILE_02);
			break;
		case 3: printf("%s\n", ERR_VFS_UPDATEFILE_03);
			break;
		case 4: printf("%s\n", ERR_VFS_UPDATEFILE_04);
			break;
	}
	
}

void removefile ( char *P1 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	int statusCode = delete_file(P1);
	if(statusCode!=-1)
		printf("removefile_FAILURE ");
	switch(statusCode)
	{
		case -1: printf("removefile_SUCCESS\n");
			break;
		case 0: printf("%s\n", ERR_VFS_REMOVEFILE_00);
			break;
		case 1: printf("%s\n", ERR_VFS_REMOVEFILE_01);
			break;
		case 2: printf("%s\n", ERR_VFS_REMOVEFILE_02);
			break;
	}

}

void movefile ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	int statusCode = move_file(P1, P2);
	if(statusCode!=-1)
		printf("movefile_FAILURE ");
	switch(statusCode)
	{
		case -1: printf("movefile_SUCCESS\n");
			break;
		case 0: printf("%s\n", ERR_VFS_MOVEFILE_00);
			break;
		case 1: printf("%s\n", ERR_VFS_MOVEFILE_01);
			break;
		case 2: printf("%s\n", ERR_VFS_MOVEFILE_02);
			break;
		/*case 5: printf("%s", ERR_VFS_MOVEFILE_05);
			break;*/
		case 6: printf("%s\n", ERR_VFS_MOVEFILE_06);
			break;
	}

}

void copyfile ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	int statusCode= copy_file(P1, P2);
	if(statusCode!=-1)
		printf("copyfile_FAILURE ");

	switch(statusCode)
	{
		case -1: printf("copyfile_SUCCESS\n");
			break;
		case 0: printf("%s\n", ERR_VFS_COPYFILE_00);
			break;
		case 1: printf("%s\n", ERR_VFS_COPYFILE_01);
			break;
		case 2: printf("%s\n", ERR_VFS_COPYFILE_02);
			break;	
		case 3: printf("%s\n", ERR_VFS_COPYFILE_03);
			break;
		case 4: printf("%s\n", ERR_VFS_COPYFILE_04);
			break;
		case 5: printf("%s\n", ERR_VFS_COPYFILE_05);
			break;
	}

}

void exportfile ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	int statusCode=export_file(P1, P2);
	if(statusCode!=-1)
		printf("exportfile_FAILURE ");
	switch(statusCode)
	{
		case -1: printf("exportfile_SUCCESS\n");
			break;
		case 0: printf("%s\n", ERR_VFS_EXPORTFILE_00);
			break;
		case 1: printf("%s\n", ERR_VFS_EXPORTFILE_01);
			break;
		case 2: printf("%s\n", ERR_VFS_EXPORTFILE_02);
			break;
		case 3: printf("%s\n", ERR_VFS_EXPORTFILE_03);
			break;
		case 4: printf("%s\n", ERR_VFS_EXPORTFILE_04);
			break;
	}

}

void searchfile ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	int statusCode = search_file(P1, P2);
	if(statusCode!=-1)
		printf("searchfile_FAILURE ");
	switch(statusCode)
	{
		case -1: printf("searchfile_SUCCESS\n");
			break;
		case 0: printf("%s\n", ERR_VFS_SEARCHFILE_00);
			break;
		case 2: printf("%s\n", ERR_VFS_SEARCHFILE_02);
			break;
	}

}

void searchcontent( char *P1, char *P2 )
{
	int statusCode = search_file_content(P1, P2);
	if(statusCode == -1)
		printf("searchcontent_SUCCESS\n");
}
